* use consistent unit suffixes.
This is a user visible change. The suffixes for the distance
option of the arcdist, interpolate, radius and position filters
and the add option of the height filter are different.
* drop unused includes
* whitespace
* terminate fatal messages.
* change simplify to process distances in meters.
This simplifies option value parsing.
There is no user visible difference.
* define MYNAME in cc not h.
#include <cmath> // for round
#include <cstdio> // for printf, sscanf
-#include <cstdlib> // for strtod
#include <tuple> // for tie, tuple
#include <QByteArray> // for QByteArray
waypointp->position());
}
- /* convert radians to float point statute miles */
- dist = radtomiles(dist);
+ /* convert radians to meters */
+ dist = radtometers(dist);
if (ed->distance > dist) {
ed->distance = dist;
void ArcDistanceFilter::init()
{
- char* fm;
-
if ((!arcfileopt && !rteopt && !trkopt) ||
(arcfileopt && (rteopt || trkopt)) ||
(rteopt && trkopt)) {
fatal(MYNAME ": Incompatible or incomplete option values!\n");
}
- pos_dist = 0;
+ pos_dist = 0.0;
if (distopt) {
- pos_dist = strtod(distopt, &fm);
-
- if ((*fm == 'k') || (*fm == 'K')) {
- /* distance is kilometers, convert to mile */
- pos_dist *= kMilesPerKilometer;
+ if (parse_distance(distopt, &pos_dist, kMetersPerMile, MYNAME) == 0) {
+ fatal(MYNAME ": No distance specified with distance option.\n");
}
}
}
return args;
}
+ static const QVector<QString> radius_units = {"mi", "km"};
if (radius) {
args << QString("-x");
args << QString("radius,distance=%1%2,lat=%3,lon=%4")
- .arg(radiusVal).arg("MK"[radiusUnit]).arg(latVal, 0, 'f', 8).arg(longVal, 0, 'f', 8);
+ .arg(radiusVal).arg(radius_units.at(radiusUnit)).arg(latVal, 0, 'f', 8).arg(longVal, 0, 'f', 8);
}
if (duplicates && (shortNames || locations)) {
args << QString("-x");
args << s;
}
+ static const QVector<QString> position_units = {"ft", "m"};
if (position) {
args << QString("-x");
- args << QString("position,distance=%1%2").arg(positionVal).arg("FM"[positionUnit]);
+ args << QString("position,distance=%1%2").arg(positionVal).arg(position_units.at(positionUnit));
}
return args;
}
#include "height.h"
#include <cmath> // for floor
#include <cstdint> // for int8_t
-#include <cstdlib> // for strtod
#define MYNAME "height"
void HeightFilter::init()
{
- char* unit;
-
+ addf = 0.0;
if (addopt != nullptr) {
- addf = strtod(addopt, &unit);
-
- if (*unit == 'f' || *unit== 'F') {
- addf = FEET_TO_METERS(addf);
- } else if ((*unit != 'm') && (*unit != 'M') && (*unit != '\0')) {
- fatal(MYNAME ": Invalid unit (\"%c\")! Please use \"m\" for meter or \"f\" for feet.\n", *unit);
+ if (parse_distance(addopt, &addf, 1.0, MYNAME) == 0) {
+ fatal(MYNAME ": No height specified with add option.");
}
- } else {
- addf = 0.0;
}
}
QVector<arglist_t> args = {
{
- "add", &addopt, "Adds a constant value to every altitude (meter, append \"f\" (x.xxf) for feet)",
+ "add", &addopt, "Adds a constant value to every altitude",
nullptr, ARGTYPE_BEGIN_REQ | ARGTYPE_FLOAT, ARG_NOMINMAX, nullptr
},
{
// interpolate even if time is running backwards.
npts = std::abs(*timespan) / max_time_step;
} else if (opt_dist != nullptr) {
- double distspan = radtomiles(gcdist(pos1, wpt->position()));
+ double distspan = radtometers(gcdist(pos1, wpt->position()));
npts = distspan / max_dist_step;
}
if (!std::isfinite(npts) || (npts >= INT_MAX)) {
void InterpolateFilter::init()
{
- char* fm;
if ((opt_time != nullptr) && (opt_dist != nullptr)) {
fatal(FatalMsg() << MYNAME ": Can't interpolate on both time and distance.");
} else if ((opt_time != nullptr) && opt_route) {
fatal(FatalMsg() << MYNAME ": interpolation time should be positive!");
}
} else if (opt_dist != nullptr) {
- max_dist_step = strtod(opt_dist, &fm);
- if ((*fm == 'k') || (*fm == 'K')) {
- /* distance is kilometers, convert to miles */
- max_dist_step *= kMilesPerKilometer;
+ if (parse_distance(opt_dist, &max_dist_step, kMetersPerMile, MYNAME) == 0) {
+ fatal(FatalMsg() << MYNAME ": no distance specified with distance option!");
}
if (max_dist_step <= 0) {
fatal(FatalMsg() << MYNAME ": interpolation distance should be positive!");
"0", nullptr, nullptr
},
{
- "distance", &opt_dist, "Distance interval in miles or kilometers",
+ "distance", &opt_dist, "Distance interval",
nullptr, ARGTYPE_END_EXCL | ARGTYPE_END_REQ | ARGTYPE_STRING,
ARG_NOMINMAX, nullptr
},
#include "src/core/datetime.h" // for DateTime
#if FILTERS_ENABLED
+#define MYNAME "Position filter"
/* tear through a waypoint queue, processing points by distance */
void PositionFilter::position_runqueue(const WaypointList& waypt_list, int qtype)
check_time = false;
if (distopt != nullptr) {
- char* fm;
- pos_dist = strtod(distopt, &fm);
-
- if (!((*fm == 'm') || (*fm == 'M'))) {
- /* distance is feet */
- pos_dist = FEET_TO_METERS(pos_dist);
+ if (parse_distance(distopt, &pos_dist, kMetersPerFoot, MYNAME) == 0) {
+ fatal(MYNAME ": No distance specified with distance option.\n");
}
}
#if FILTERS_ENABLED
+#define MYNAME "Radius filter"
void RadiusFilter::process()
{
foreach (Waypoint* waypointp, *global_waypoint_list) {
- double dist = radtomiles(gcdist(waypointp->position(),
+ double dist = radtometers(gcdist(waypointp->position(),
home_pos->position()));
if ((dist >= pos_dist) == !exclopt) {
pos_dist = 0;
if (distopt != nullptr) {
- char* fm;
- pos_dist = strtod(distopt, &fm);
-
- if ((*fm == 'k') || (*fm == 'K')) {
- /* distance is kilometers, convert to miles */
- pos_dist *= kMilesPerKilometer;
+ if (parse_distance(distopt, &pos_dist, kMetersPerMile, MYNAME) == 0) {
+ fatal(MYNAME ": No distance specified with distance option.\n");
}
}
option radius asroute Put resulting waypoints in route of this name string https://www.gpsbabel.org/WEB_DOC_DIR/filter_radius.html#fmt_radius_o_asroute
interpolate Interpolate between trackpoints https://www.gpsbabel.org/WEB_DOC_DIR/filter_interpolate.html
option interpolate time Time interval in seconds float 0 https://www.gpsbabel.org/WEB_DOC_DIR/filter_interpolate.html#fmt_interpolate_o_time
-option interpolate distance Distance interval in miles or kilometers string https://www.gpsbabel.org/WEB_DOC_DIR/filter_interpolate.html#fmt_interpolate_o_distance
+option interpolate distance Distance interval string https://www.gpsbabel.org/WEB_DOC_DIR/filter_interpolate.html#fmt_interpolate_o_distance
option interpolate route Interpolate routes instead boolean https://www.gpsbabel.org/WEB_DOC_DIR/filter_interpolate.html#fmt_interpolate_o_route
height Manipulate altitudes https://www.gpsbabel.org/WEB_DOC_DIR/filter_height.html
-option height add Adds a constant value to every altitude (meter, append "f" (x.xxf) for feet) float https://www.gpsbabel.org/WEB_DOC_DIR/filter_height.html#fmt_height_o_add
+option height add Adds a constant value to every altitude float https://www.gpsbabel.org/WEB_DOC_DIR/filter_height.html#fmt_height_o_add
option height wgs84tomsl Converts WGS84 ellipsoidal height to orthometric height (MSL) boolean https://www.gpsbabel.org/WEB_DOC_DIR/filter_height.html#fmt_height_o_wgs84tomsl
track Manipulate track lists https://www.gpsbabel.org/WEB_DOC_DIR/filter_track.html
option track move Correct trackpoint timestamps by a delta string https://www.gpsbabel.org/WEB_DOC_DIR/filter_track.html#fmt_track_o_move
correct Use coords from duplicate points
interpolate Interpolate between trackpoints
time Time interval in seconds
- distance Distance interval in miles or kilometers
+ distance Distance interval
route Interpolate routes instead
nuketypes Remove all waypoints, tracks, or routes
waypoints Remove all waypoints from data stream
del Delete source data after transformation
timeless Create transformed points without times
height Manipulate altitudes
- add Adds a constant value to every altitude (meter, ap
+ add Adds a constant value to every altitude
wgs84tomsl Converts WGS84 ellipsoidal height to orthometric h
swap Swap latitude and longitude of all loaded points
validate Validate internal data structures
#include "defs.h"
#include "smplrout.h"
-#include "grtcirc.h" // for gcdist, linedist, radtometers, radtomiles, linepart
+#include "grtcirc.h" // for gcdist, linedist, radtometers, linepart
#include "src/core/datetime.h" // for DateTime
double track_error;
switch (metric) {
case metric_t::crosstrack:
- track_error = radtomiles(linedist(
+ track_error = radtometers(linedist(
wpt1->position(),
wpt2->position(),
wpt3->position()));
break;
case metric_t::length:
- track_error = radtomiles(
+ track_error = radtometers(
gcdist(wpt1->position(), wpt3->position()) +
gcdist(wpt3->position(), wpt2->position()) -
gcdist(wpt1->position(), wpt2->position()));
if (metric == metric_t::relative) {
error = strtod(erroropt, nullptr);
} else {
- int res = parse_distance(erroropt, &error, 1.0, MYNAME);
- if (res == 0) {
- error = 0;
- } else if (res == 2) { /* parameter with unit */
- error = METERS_TO_MILES(error);
+ if (parse_distance(erroropt, &error, kMetersPerMile, MYNAME) == 0) {
+ fatal(MYNAME ": No value specified with error option.\n");
}
}
}
echo 'IFIELD PATH_DISTANCE_METERS, "", "%.0f"' >> ${TMPDIR}/interp.style
echo 'IFIELD ALT_METERS, "", "%.3f"' >> ${TMPDIR}/interp.style
echo 'IFIELD TIMET_TIME_MS, "", "%lld"' >> ${TMPDIR}/interp.style
-gpsbabel -t -i gpx -f ${REFERENCE}/track/simpletrack.gpx -x interpolate,distance=50m -o gpx -F ${TMPDIR}/interp.gpx -o xcsv,style=${TMPDIR}/interp.style -F ${TMPDIR}/interp.csv
+gpsbabel -t -i gpx -f ${REFERENCE}/track/simpletrack.gpx -x interpolate,distance=50mi -o gpx -F ${TMPDIR}/interp.gpx -o xcsv,style=${TMPDIR}/interp.style -F ${TMPDIR}/interp.csv
compare ${REFERENCE}/track/interptrack.gpx ${TMPDIR}/interp.gpx
compare ${REFERENCE}/track/interptrack.csv ${TMPDIR}/interp.csv
+gpsbabel -t -i gpx -f ${REFERENCE}/track/simpletrack.gpx -x interpolate,distance=50 -o gpx -F ${TMPDIR}/interp2.gpx
+compare ${REFERENCE}/track/interptrack.gpx ${TMPDIR}/interp2.gpx
+
gpsbabel -t -i gpx -f ${REFERENCE}/track/simpletrack.gpx -x interpolate,time=1 -o gpx -F ${TMPDIR}/tinterp.gpx -o xcsv,style=${TMPDIR}/interp.style -F ${TMPDIR}/tinterp.csv
compare ${REFERENCE}/track/tinterptrack.gpx ${TMPDIR}/tinterp.gpx
compare ${REFERENCE}/track/tinterptrack.csv ${TMPDIR}/tinterp.csv
#
rm -f ${TMPDIR}/filterpos.csv1 ${TMPDIR}/filterpos.csv2
gpsbabel -i geo -f ${REFERENCE}/geocaching.loc -o csv -F ${TMPDIR}/filterpos.csv1
-gpsbabel -i geo -f ${REFERENCE}/geocaching.loc -f ${REFERENCE}/geocaching.loc -x position,distance=5f \
+gpsbabel -i geo -f ${REFERENCE}/geocaching.loc -f ${REFERENCE}/geocaching.loc -x position,distance=5ft \
-o csv -F ${TMPDIR}/filterpos.csv2
sort_and_compare ${TMPDIR}/filterpos.csv1 ${TMPDIR}/filterpos.csv2
points that are further away are discarded.
</para>
<para>
-Distances may be specified in miles (3M) or kilometers (5K). If no units
-are specified, the distance is assumed to be in miles.
+The units may be specified by appending a suffix to the supplied number:
+</para>
+<simplelist type="vert">
+<member>'m' for meters, e.g. 3500.0m</member>
+<member>'ft' or 'feet' for feet, e.g. 11483ft</member>
+<member>'k' or 'km' for kilometers, e.g 3.5000km</member>
+<member>'nm' for nautical miles, e.g. 1.8898nm</member>
+<member>'mi' for miles, e.g. 2.1748mi</member>
+<member>'fa' for fathoms, e.g. 1913.82fa</member>
+</simplelist>
+<para>
+If no units are specified, the units are assumed to be miles.
</para>
Adds a constant value to every altitude. You can specify negative numbers to subtract the value.
</para>
<para>
-If no unit is specified, (m)eters are assumed. You can override this by attaching a "f" for feet to the number.
+The units may be specified by appending a suffix to the supplied number:
+</para>
+<simplelist type="vert">
+<member>'m' for meters, e.g. 3.5m</member>
+<member>'ft' or 'feet' for feet, e.g. 11.483ft</member>
+<member>'k' or 'km' for kilometers, e.g 0.0035km</member>
+<member>'nm' for nautical miles, e.g. 0.0018898nm</member>
+<member>'mi' for miles, e.g. 0.0021748mi</member>
+<member>'fa' for fathoms, e.g. 1.9138fa</member>
+</simplelist>
+<para>
+If no units are specified, the units are assumed to be meters.
</para>
<para>
-This option specifies the maximum allowable distance between points in the
+This option specifies the maximum allowable distance between adjacent points in the
track. If two points in the track are further apart than this value, new
points will be inserted between them.
</para>
<para>
-This value may be specified in units of miles (3M, 3.5M) or kilometers (5K, 5.7K). If
-no units are specified, the units are assumed to be miles.
+The units may be specified by appending a suffix to the supplied number:
+</para>
+<simplelist type="vert">
+<member>'m' for meters, e.g. 3500.0m</member>
+<member>'ft' or 'feet' for feet, e.g. 11483ft</member>
+<member>'k' or 'km' for kilometers, e.g 3.5000km</member>
+<member>'nm' for nautical miles, e.g. 1.8898nm</member>
+<member>'mi' for miles, e.g. 2.1748mi</member>
+<member>'fa' for fathoms, e.g. 1913.82fa</member>
+</simplelist>
+<para>
+If no units are specified, the units are assumed to be miles.
</para>
<para>
Either this option or the <option>time</option> must be specified.
<para>
-This option specifies the maximum allowable time interval between points in the
+This option specifies the maximum allowable time interval between adjacent points in the
track. If two points in the track are further apart than this value, new
points will be inserted between them.
</para>
two points are closer than this distance, only one of them is kept.
</para>
<para>
-Distances may be expressed in feet (30f) or meters (10m). If no unit is
-specified, the distance is assumed to be in feet.
+The units may be specified by appending a suffix to the supplied number:
+</para>
+<simplelist type="vert">
+<member>'m' for meters, e.g. 3500.0m</member>
+<member>'ft' or 'feet' for feet, e.g. 11483ft</member>
+<member>'k' or 'km' for kilometers, e.g 3.5000km</member>
+<member>'nm' for nautical miles, e.g. 1.8898nm</member>
+<member>'mi' for miles, e.g. 2.1748mi</member>
+<member>'fa' for fathoms, e.g. 1913.82fa</member>
+</simplelist>
+<para>
+If no units are specified, the units are assumed to be feet.
</para>
<option>exclude</option> option is specified.)
</para>
<para>
-Distances may be expressed in miles (3M) or kilometers (4K). If no units
-are provided, the distance is assumed to be in miles.
+The units may be specified by appending a suffix to the supplied number:
+</para>
+<simplelist type="vert">
+<member>'m' for meters, e.g. 3500.0m</member>
+<member>'ft' or 'feet' for feet, e.g. 11483ft</member>
+<member>'k' or 'km' for kilometers, e.g 3.5000km</member>
+<member>'nm' for nautical miles, e.g. 1.8898nm</member>
+<member>'mi' for miles, e.g. 2.1748mi</member>
+<member>'fa' for fathoms, e.g. 1913.82fa</member>
+</simplelist>
+<para>
+If no units are specified, the units are assumed to be miles.
</para>